#ifndef LOGGER_H
#define LOGGER_H

#include <sstream>
#include <string>

#include "Types.h"
#include "Entry.h"
#include "LogOutput.h"

namespace logging {

class Logger;
class end;

class end
{
	friend Logger& operator<<(Logger &logger, const end e);
};

Logger& operator<<(Logger &logger, const end e); 

class Logger 
{
	friend Logger& operator<<(Logger &logger, const end e);

public:
	Logger(LogOutput *output, const char *ns, Level currentLevel, Level level);
	Logger(const Logger& old);
	~Logger();

	inline Logger &operator<<(bool t) { _msg << (t ? "true" : "false"); return *this; }
	inline Logger &operator<<(char t) { _msg << t; return *this; }
	inline Logger &operator<<(short t) { _msg << t; return *this; }
	inline Logger &operator<<(unsigned short t) { _msg << t; return *this; }
	inline Logger &operator<<(int t) { _msg << t; return *this; }
	inline Logger &operator<<(unsigned int t) { _msg << t; return *this; }
	inline Logger &operator<<(long t) { _msg << t; return *this; }
	inline Logger &operator<<(unsigned long t) { _msg << t; return *this; }
	inline Logger &operator<<(float t) { _msg << t; return *this; }
	inline Logger &operator<<(double t) { _msg << t; return *this; }
	inline Logger &operator<<(const char* t) { _msg << t; return *this; }
	inline Logger &operator<<(const std::string& t) { _msg << t; return *this; }
	inline Logger &operator<<(const void * t) { _msg << t; return *this; }

protected:
	void record() const;

private:
	LogOutput *_output;
	char *_namespace;
	Level _currentLevel;
	Level _level;
	std::stringstream _msg;
};

}

#endif /* LOGGER_H */
